/**
 * main.cpp is part of cbs-framework.
 *
 * cbs-framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * cbs-framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with cbs-framework.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mainwindow.h"
#include <QApplication>
#include <cstdlib>
#include "utils/logging/logmanager.h"
#include "utils/logging/logger.h"
#include "cbs/connector/xmlmodelconnector.h"
#include "cbs/model.h"
#include "cbs/minizinc/minizinccodegenerator.h"
#include <QFile>
#include <QTextStream>
#include <tclap/CmdLine.h>

int main( int argc, char * argv [] )
{
    const std::string fileLongArg                = "file";
    const std::string fileShortArg               = "f";
    const std::string fileArgsDescription        = "Xml file containing the constraints model to schedule.";
    const std::string allSolutionsLongArg        = "all-solutions";
    const std::string allSolutionsShortArg       = "a";
    const std::string allSolutionsArgDescription = "Get all schedules that satisfy the constraint model";
    const std::string programDescription         = "cbs-framework Copyright (C) 2013 Jose Luzon Martin\nThis program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\nThis is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details";
    const std::string programVersion             = "0.9";

    try
    {
        TCLAP::CmdLine cmd(programDescription, ' ', programVersion );

        TCLAP::ValueArg< std::string > fileArg( fileShortArg, fileLongArg, "", true, fileArgsDescription, "string" );
        cmd.add( fileArg );

        TCLAP::SwitchArg allSolutionsArg( allSolutionsShortArg, allSolutionsLongArg, allSolutionsArgDescription, cmd, false );

        cmd.parse( argc, argv );

        std::string file  = fileArg.getValue();
        bool allSolutions = allSolutionsArg.getValue();

        GET_LOG_MGR().SubscribeConsoleLogger( "LOG" );

        XmlModelConnector connector( file );
        if( connector.Load() )
        {
            Model * model = connector.GetModel();
            if( model )
            {
                MiniZincCodeGenerator codeGenerator;
                model->Accept( &codeGenerator );

                QFile file("./data.dzn");
                if( file.open( QIODevice::WriteOnly | QIODevice::Text ) )
                {
                    QTextStream out( &file );
                    out << codeGenerator.Print().c_str();
                }

                int x = EXIT_SUCCESS;
                if( allSolutions )
                    x = std::system( "mzn-gecode --all-solutions mzn.mzn data.dzn" );
                else
                    x = std::system( "mzn-gecode mzn.mzn data.dzn" );

                // optional, as QFile destructor will already do it:
                file.close();
            }
        }
    }
    catch ( TCLAP::ArgException & e )
    {
        Logger * log = GET_LOG_MGR().GetLogger( "LOG" );
        if( log )
            log->LogError() << e.error() << " for arg " << e.argId();
    }
    catch( ... )
    {
        Logger * log = GET_LOG_MGR().GetLogger( "LOG" );
        if( log )
            log->LogError() << "Unexpected Error!";
    }

    //QApplication a(argc, argv);
    //MainWindow w;
    //w.show();
    //return a.exec();

    return EXIT_SUCCESS;
}

